<?php

/*
发布，订阅模式
    一个消息发给多个消费者，这种模式称为发布，订阅模式
    RabbitMQ 核心思想：一个生产者并不会直接往一个队列中发送消息，事实上，生产者根本不知道它发送的消息将被转发到那个消费者中，
  解读:
    1.一个生产者，多个消费者
    2.每个消费者都有属于自己的队列
    3.生产者没有直接将消息发送到队列中，而是发送到交换机(Exchange)，再由交换机分发到队列中去
    4.订阅模式可以实现，一个消息被多个消费者消费

    交换机(Exchange)的作用：
        生产者发送消息不会像传统方式直接将消息投递到队列中，而是将消息投递到交换机当中,再由交换机转发到具体的队列中，队列在将消息以推送或者拉取的方式给消费者进行消费，这点上和我们nginx相似

        交换机的作用根据具体的路由策略分发到不同的队列中，交换机有四种类型，
        1、Direct exchange(直连交换机) 是根据消息携带的路由键（routing key）将消息投递给队列
        2、Fanout exchange(扇形交换机) 将消息路由给绑定到他身上的所有队列
        3、Topic exchange(主题交换机) 队列通过路由键绑定到交换机上，然后，交换机根据消息里的路由值，将消息路由给一个或者多个绑定队列
        4、Headers exchange(头交换机) 类似主题交换机，但是头交换机使用多个消息属性来代替路由键建立路由规则。通过判断消息头的值能否与指定的绑定相匹配来确立路由规则

*/

$exchangeName = 'logs';

$connection = new AMQPConnection(array('host' => '127.0.0.1', 'port' => '5672', 'vhost' => '/', 'login' => 'guest', 'password' => 'guest'));
$connection->connect() or die("Cannot connect to the broker!\n");
$channel = new AMQPChannel($connection);
$exchange = new AMQPExchange($channel);
$exchange->setName($exchangeName);
$exchange->setType(AMQP_EX_TYPE_FANOUT);
//$exchange->declare();
$exchange->declareExchange();
$queue = new AMQPQueue($channel);
$queue->setFlags(AMQP_EXCLUSIVE);
//$exchange->declare();
$queue->declareQueue();
$queue->bind($exchangeName, '');

var_dump('[*] Waiting for messages. To exit press CTRL+C');
while (TRUE) {
    $queue->consume('callback');
}
$connection->disconnect();

function callback($envelope, $queue) {
    $msg = $envelope->getBody();
    var_dump(" [x] Received:" . $msg);
    $queue->nack($envelope->getDeliveryTag());
}